package com.gframework.util;

import java.util.Collection;
import java.util.Iterator;
import java.util.function.Function;

/**
 * 支持拦截操作的Iterator迭代对象.
 * <p>
 * 本类存储的基类数据依然是Iterator，只是每次执行next之前都可以对数据进行特定操作处理。
 * <p>
 * 通常有些时候对数据的某些操作会非常影响性能，但是却显得不是那么必要，因为可能根本就用不到它。
 * 最好的情况是，在使用到的时候在对其进行某些操作，如果你有这样的需求，那么就可以使用此迭代器
 * 
 * @since 1.0.0
 * @author Ghwolf
 * @param <E> 数据泛型类型
 */
public class NextInterceptorIterator<E> implements Iterator<E> {

	/**
	 * 实际迭代对象
	 */
	private final Iterator<?> iter;
	/**
	 * 操作函数
	 */
	private final Function<Object, E> handle;

	/**
	 * 创建一个具有指定拦截器的迭代器对象.
	 * <p>迭代器的类型是任意的，他可以是任何类型，但是一定要能够被转换为指定类型，否则就会出现{@link ClassCastException}。
	 * @param iter 迭代器
	 * @param handle 拦截器
	 */
	public NextInterceptorIterator(Iterator<?> iter, Function<Object, E> handle) {
		this.iter = iter;
		this.handle = handle;
	}
	/**
	 * 创建一个具有指定拦截器的迭代器对象.
	 * <p>迭代器的类型是任意的，他可以是任何类型，但是一定要能够被转换为指定类型，否则就会出现{@link ClassCastException}。
	 * @param collection 集合对象
	 * @param handle 拦截器
	 */
	public NextInterceptorIterator(Collection<?> collection, Function<Object, E> handle) {
		this(collection.iterator(),handle);
	}

	@Override
	public boolean hasNext() {
		return iter.hasNext();
	}

	@SuppressWarnings("unchecked")
	@Override
	public E next() {
		Object o = iter.next();
		return handle == null ? (E) o : handle.apply(o);
	}
}
